package com.pond.pond.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import com.pond.common.core.utils.DateUtils;
import com.pond.pond.domain.Appointment;
import com.pond.pond.domain.AppointmentTimeSegment;
import com.pond.pond.mapper.AppointmentMapper;
import com.pond.pond.service.AppointmentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.pond.pond.mapper.PondSeatMapper;
import com.pond.pond.domain.PondSeat;
import com.pond.pond.service.IPondSeatService;

/**
 * 钓位信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-06-09
 */
@Service
public class PondSeatServiceImpl implements IPondSeatService 
{
    @Autowired
    private PondSeatMapper pondSeatMapper;

    @Autowired
    private AppointmentMapper appointmentMapper;


    /**
     * 查询钓位信息
     * 
     * @param id 钓位信息主键
     * @return 钓位信息
     */
    @Override
    public PondSeat selectPondSeatById(Long id)
    {
        return pondSeatMapper.selectPondSeatById(id);
    }

    @Override
    public List<PondSeat> selectPondSeatList(PondSeat pondSeat) {
        List<PondSeat> pondSeatList = pondSeatMapper.selectPondSeatList(pondSeat);
        if (pondSeatList.isEmpty()) {
            return pondSeatList;
        }

        // 1. 提取所有 pondId（去重）
        Set<Long> pondIds = pondSeatList.stream()
                .map(PondSeat::getPondId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        if (pondIds.isEmpty()) {
            return pondSeatList;
        }

        // 2. 查询所有 pondId 下的预约列表
        List<Appointment> allAppointments = new ArrayList<>();
        for (Long pondId : pondIds) {
            Appointment query = new Appointment();
            query.setPondId(pondId);
            List<Appointment> appointments = appointmentMapper.selectAppointmentList(query);
            allAppointments.addAll(appointments);
        }

        // 3. 批量获取所有预约id
        List<Long> appointmentIds = allAppointments.stream()
                .map(Appointment::getId)
                .collect(Collectors.toList());

        // 4. 批量查询所有时间段
        if (appointmentIds.isEmpty()) {
            return pondSeatList;
        }
        List<AppointmentTimeSegment> allSegments = appointmentMapper.selectSegmentsByAppointmentIds(appointmentIds);

        // 5. 按 appointmentId 分组时间段
        Map<Long, List<AppointmentTimeSegment>> segmentMap = allSegments.stream()
                .filter(seg -> seg.getAppointmentId() != null)
                .collect(Collectors.groupingBy(AppointmentTimeSegment::getAppointmentId));

        // 6. 给每个预约赋值时间段
        for (Appointment appointment : allAppointments) {
            appointment.setTimeSegments(segmentMap.getOrDefault(appointment.getId(), Collections.emptyList()));
        }

        // 7. 当前时间
        LocalDateTime now = LocalDateTime.now();

        // 8. 构建 seatId -> 状态
        Map<Long, Integer> seatStatusMap = new HashMap<>();
        for (Appointment appointment : allAppointments) {
            // 过滤掉无效状态的预约（2取消、4爽约等）
            if (appointment.getStatus() != null && (appointment.getStatus() == 2 || appointment.getStatus() == 4)) {
                continue; // 跳过无效预约
            }
            List<AppointmentTimeSegment> segments = appointment.getTimeSegments();
            if (segments == null) {
                continue;
            }
            for (AppointmentTimeSegment segment : segments) {
                if (segment.getSeatId() == null || segment.getAppointmentDate() == null) {
                    continue;
                }
                LocalDateTime startDateTime = LocalDateTime.of(segment.getAppointmentDate(), segment.getStartTime());
                LocalDateTime endDateTime = LocalDateTime.of(segment.getAppointmentDate(), segment.getEndTime());
                LocalDateTime earlyLimit = startDateTime.minusMinutes(45);

                if (now.isAfter(startDateTime) && now.isBefore(endDateTime)) {
                    seatStatusMap.put(segment.getSeatId(), 2); // 使用中
                } else if (now.isAfter(earlyLimit) && now.isBefore(endDateTime)) {
                    seatStatusMap.putIfAbsent(segment.getSeatId(), 1); // 已预约（提前45分钟内）
                }
            }
        }


        // 9. 设置钓位状态
        for (PondSeat p : pondSeatList) {
            Long seatId = p.getId();
            Integer reservable = p.getReservable(); // 0=不可预约, 1=可预约
            Integer status = p.getStatus();         // 钓位状态

            if (status != null && (status == 1 || status == 3)) {
                // 已预约或禁用时，reservable 必须是 0（不可预约）
                p.setReservable(0);
            } else if (reservable != null && reservable == 0) {
                // reservable=0时，强制状态为禁用3
                p.setStatus(3);
            } else {
                // 预约状态映射
                if (seatStatusMap.containsKey(seatId)) {
                    p.setStatus(seatStatusMap.get(seatId));
                    // 使用中(2)或已预约(1)，对应reservable设0
                    if (p.getStatus() == 1 || p.getStatus() == 2) {
                        p.setReservable(0);
                    }
                } else {
                    // 空闲，且不是禁用，reservable设1
                    if (status == null || status == 0) {
                        p.setStatus(0);
                        p.setReservable(1);
                    }
                }
            }
        }


        return pondSeatList;
    }


    /**
     * 新增钓位信息
     *
     * @param pondSeat 钓位信息
     * @return 结果
     */
    @Override
    public int insertPondSeat(PondSeat pondSeat)
    {
        pondSeat.setCreateTime(DateUtils.getNowDate());

        if (Boolean.TRUE.equals(pondSeat.getIsBatch())) {
            Integer count = pondSeat.getBatchCount();
            String prefix = pondSeat.getCodePrefix();

            if (count == null || prefix == null) {
                throw new IllegalArgumentException("批量插入时，batchCount 和 codePrefix 必须传入！");
            }

            ArrayList<PondSeat> seatList = new ArrayList<>();
            for (int i = 1; i <= count; i++) {
                PondSeat seat = new PondSeat();
                BeanUtils.copyProperties(pondSeat, seat);
                seat.setCode(prefix + String.format("%02d", i));
                seat.setCreateTime(DateUtils.getNowDate());
                seat.setPriceSegmentId(pondSeat.getPriceSegmentId());
                seatList.add(seat);
            }

            return pondSeatMapper.batchInsertPondSeat(seatList);
        } else {
            if (pondSeat.getCode() == null) {
                throw new IllegalArgumentException("非批量插入时，code 字段必须传入");
            }
            return pondSeatMapper.insertPondSeat(pondSeat);
        }
    }


    /**
     * 修改钓位信息
     * 
     * @param pondSeat 钓位信息
     * @return 结果
     */
    @Override
    public int updatePondSeat(PondSeat pondSeat)
    {
        pondSeat.setUpdateTime(DateUtils.getNowDate());
        return pondSeatMapper.updatePondSeat(pondSeat);
    }

    /**
     * 批量删除钓位信息
     * 
     * @param ids 需要删除的钓位信息主键
     * @return 结果
     */
    @Override
    public int deletePondSeatByIds(Long[] ids)
    {
        return pondSeatMapper.deletePondSeatByIds(ids);
    }

    /**
     * 删除钓位信息信息
     * 
     * @param id 钓位信息主键
     * @return 结果
     */
    @Override
    public int deletePondSeatById(Long id)
    {
        return pondSeatMapper.deletePondSeatById(id);
    }
}
